package com.sojson.util.sms.impl;

import java.util.Date;
import java.util.Map;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.sojson.constant.Constant;
import com.sojson.util.DateUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.ali.AliUtil;
import com.sojson.util.ali.bean.AliConfig;
import com.sojson.util.json.JsonUtil;
import com.sojson.util.properties.PropertiesUtil;
import com.sojson.util.sms.SmsUtilInterface;
import com.sojson.util.text.Convert;

/**
 * 短信工具类实现类
 * 
 * Created on 17/6/7. 短信API产品的DEMO程序,工程中包含了一个SmsDemo类，直接通过
 * 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可) 工程依赖了2个jar包(存放在工程的libs目录下)
 * 1:aliyun-java-sdk-core.jar 2:aliyun-java-sdk-dysmsapi.jar
 *
 * 备注:Demo工程编码采用UTF-8 国际短信发送请勿参照此DEMO
 * 
 * @author liu
 * @Date 2020-06-28 15:37:57
 * @Description
 *
 */
public class SmsUtilImpl implements SmsUtilInterface {

    private static SmsUtilImpl smsUtilsImpl;

    static {
        // SMS调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout",
            Convert.toStr(
                PropertiesUtil.getNumberFormat(Constant.PROPERTIES.getProperty("so.sms.defaultConnectTimeout")),
                1000 * 10 + ""));
        System.setProperty("sun.net.client.defaultReadTimeout",
            Convert.toStr(PropertiesUtil.getNumberFormat(Constant.PROPERTIES.getProperty("so.sms.defaultReadTimeout")),
                1000 * 10 + ""));
    }

    private SmsUtilImpl() {}

    /**
     * 发送短信接口
     * 
     * @param templateNameCode 阿里云短信模板代码
     * @param param 验证码，从SmsTemplate类获取
     * @param tel 发送到哪个手机号
     * @return
     * @throws Exception 
     */
    @SuppressWarnings("deprecation")
    @Override
    public SendSmsResponse sendSms(String templateNameCode, Map<String, String> param, String tel) throws Exception {
        AliConfig config = AliUtil.getConfigSms();

        // 初始化acsClient,暂不支持region化
        IClientProfile profile =
            DefaultProfile.getProfile("cn-hangzhou", config.getAccessKey(), config.getAccessSecret());
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", PRODUCT, DOMAIN);
        IAcsClient acsClient = new DefaultAcsClient(profile);

        // 组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        // 必填:待发送手机号
        request.setPhoneNumbers(tel);
        // 必填:短信签名-可在短信控制台中找到
        request.setSignName(config.getSmsSign());
        // 必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(templateNameCode);
        if (param != null) {
            // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
            request.setTemplateParam(JsonUtil.objectToJsonAll(param));
        }

        // 选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        // request.setSmsUpExtendCode("90997");

        // 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        request.setOutId("yourOutId");

        // hint 此处可能会抛出异常，注意catch
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);

        return sendSmsResponse;
    }

    /**
     * 查明细接口
     * 
     * @param tel
     * @param bizId 此ID从状态信息类SendSmsResponse获取
     * @param pageSum
     * @param pageSize
     * @param date
     * @return
     * @throws Exception
     */
    @SuppressWarnings("deprecation")
    @Override
    public QuerySendDetailsResponse querySendDetails(String tel, String bizId, Long pageSum, Long pageSize, Date date)
        throws Exception {
        AliConfig config = AliUtil.getConfig();

        // 初始化acsClient,暂不支持region化
        IClientProfile profile =
            DefaultProfile.getProfile("cn-hangzhou", config.getAccessKey(), config.getAccessSecret());
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", PRODUCT, DOMAIN);
        IAcsClient acsClient = new DefaultAcsClient(profile);

        // 组装请求对象
        QuerySendDetailsRequest request = new QuerySendDetailsRequest();
        // 必填-号码
        request.setPhoneNumber(tel);
        // 可选-流水号
        request.setBizId(bizId);
        // 必填-发送日期 支持30天内记录查询，格式yyyyMMdd
        request.setSendDate(DateUtil.dateToString(date, DateUtil.YYYYMMDD));
        // 必填-页大小
        request.setPageSize(pageSize);
        // 必填-当前页码从1开始计数
        request.setCurrentPage(pageSum);

        // hint 此处可能会抛出异常，注意catch
        QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);

        return querySendDetailsResponse;
    }

    /**
     * 判断一个对象是否是空(空对象)
     * 
     * @param obj
     * @return
     */
    private static boolean isBlankObject(Object obj) {
        return StringUtil.isBlankObject(obj);
    }

    public static SmsUtilImpl getInstances() {
        if (isBlankObject(smsUtilsImpl)) {
            smsUtilsImpl = new SmsUtilImpl();
        }
        return smsUtilsImpl;
    }

}